﻿#include "daq207_device.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <cstring>

#ifdef __cplusplus
extern "C"
{
#endif
#include "libdaq/device/DAQ207/DAQ207_wrapper.h"
#include "libdaq/backend/usb_server/usb_server_wrapper.h"
#include "libdaq/device/base_device_config.h"
#ifdef __cplusplus
}
#endif

using namespace std;
using namespace libdaq::device;

// 测试DAQ207设备
bool testDAQ207() {
    DeviceType type = DeviceType::DeviceType_DAQ207;
    uint32_t* usb_server_handle = USBServer_New(type);
    if(usb_server_handle == nullptr){
        cout << "Failed to create USB Server" << endl;
        return false;
    }

    USBServer_StartSearch(usb_server_handle);

    uint32_t *client = nullptr;
    // 如果是多机，始终传入0去获取设备即可
    while (USBServer_GetDeviceCount(usb_server_handle))
    {
        client = USBServer_GetClientByIndex(usb_server_handle, 0);
        if(client){
            break;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    
    uint32_t *device_handle = DAQ207_New();
    if (!DAQ207_UseBackend(device_handle, client))
    {
        cout << "Failed to use backend" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }
    
    if (!DAQ207_InitializeDevice(device_handle)) {
        cout << "Failed to initialize device" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }
    
    if (!DAQ207_ConnectedDevice(device_handle)) {
        cout << "Failed to connect device" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 双边沿触发 普通触发 超时100ms 触发电平100mV
    const LockzhinerADCTriggerType trigger_type = LockzhinerADCTriggerType::DoubleEdge;
    const LockzhinerADCTriggerMode trigger_mode = LockzhinerADCTriggerMode::Common;
    const LockzhinerADCChannel trigger_channel = LockzhinerADCChannel::ADCChannelAINNone;
    const int trigger_level = 100;
    if (!DAQ207_ConfigADCTrigger(device_handle, static_cast<int>(trigger_type), static_cast<int>(trigger_mode), static_cast<int>(trigger_channel), trigger_level)) {
        cout << "Failed to config trigger" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 设置采样率500k
    const LockzhinerADCSampleRate sample_rate = LockzhinerADCSampleRate::ADCSampleRate_500_K;
    if (!DAQ207_ConfigADCSampleRate(device_handle, static_cast<int>(sample_rate))) {
        cout << "Failed to config sample rate" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 电压范围±10V
    const LockzhinerADCVoltage voltage = LockzhinerADCVoltage::ADCVoltage_10_V;
    if (!DAQ207_ConfigADCVoltage(device_handle, static_cast<int>(voltage))) {
        cout << "Failed to config voltage" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 设置开启2通道
    const uint8_t channel_mask = 0x03;
    if (!DAQ207_ConfigADCChannel(device_handle, channel_mask)) {
        cout << "Failed to config ADC channel" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 设置采集长度4920
    const uint32_t trigger_length = 4920;
    if (!DAQ207_ConfigADCTriggerLength(device_handle, trigger_length)) {
        cout << "Failed to config trigger length" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 设置全通道DC ( 1代表 DC，0 代表 AC)
    const uint8_t acdc_channel = 0x03;
    if (!DAQ207_ConfigACDC(device_handle, acdc_channel)) {
        cout << "Failed to config ACDC" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    //停止上次采集
    if (!DAQ207_StopCollection(device_handle)) {
        cout << "Failed to stop collection" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 等待1秒 以免下发太快 停止采集和开始采集的命令执行混乱
    std::this_thread::sleep_for(std::chrono::milliseconds(3000));

    // 开始采集
    if (!DAQ207_StartCollection(device_handle)) {
        cout << "Failed to start collection" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 等待1秒 以免下发太快 命令执行混乱
    std::this_thread::sleep_for(std::chrono::milliseconds(3000));

    // 软件触发
    if (!DAQ207_ConfigADCTriggerSource(device_handle)) {
        cout << "Failed to config trigger source" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    // 读取数据
    int channel_count = DAQ207_GetADCLegalChannelSize(device_handle);
    for (int channel = 0; channel < channel_count; channel++) {
        float read_buffer[trigger_length];
        if (!DAQ207_TryReadData_Batch(device_handle, channel, read_buffer, trigger_length))
        {
            channel --;
            continue;
        }
        cout << "Successfully read 4920 data points from channel " << (channel + 1) << endl;

        // 输出前10个值
        cout << "Channel " << (channel + 1) << " first 10 values: ";
        for (int i = 0; i < 10 && i < trigger_length; i++) {
            cout << read_buffer[i];
            if (i < 9 && i < trigger_length - 1) {
                cout << ", ";
            }
        }
        cout << endl;
    }
    
    // 停止采集
    if (!DAQ207_StopCollection(device_handle)) {
        cout << "Failed to stop collection" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }

    if (!DAQ207_DisconnectedDevice(device_handle))
    {
        cout << "Failed to disconnect device" << endl;
        DAQ207_Delete(device_handle);
        USBServer_Delete(usb_server_handle);
        return false;
    }
    
    DAQ207_Delete(device_handle);
    USBServer_Delete(usb_server_handle);

    cout << "Successfully test DAQ207" << endl;
    return true;
} 
